package com.huafeng.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huafeng.commonutil.CheckUtils;
import com.huafeng.commonutil.MenuHelper;
import com.huafeng.commonutil.RouterHelper;
import com.huafeng.mapper.SysMenuMapper;
import com.huafeng.model.base.Result;
import com.huafeng.model.constant.IdConstant;
import com.huafeng.model.entity.SysMenu;
import com.huafeng.model.entity.SysRoleMenu;
import com.huafeng.model.vo.AssignMenuVo;
import com.huafeng.model.vo.RouterVo;
import com.huafeng.service.SysMenuService;
import com.huafeng.service.SysRoleMenuService;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 花风
 * @date 2023/8/16 21:24
 * @Description SysMenuServiceImpl
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private SysRoleMenuService sysRoleMenuService;


    @Override
    public Result findNodes() {
        List<SysMenu> roots = this.query().eq("parent_id", IdConstant.MENU_ROOT_ID).list();
        // 获取所有菜单
        List<SysMenu> sysMenuList = this.list();

        if (CollectionUtils.isEmpty(roots) || CollectionUtils.isEmpty(sysMenuList)){
            return Result.ok();
        }

        return Result.ok(MenuHelper.buildTree(roots,sysMenuList));
    }

    @Override
    public List<RouterVo> findUserMenulist(List<Long> roleIds) {
        List<SysMenu> roots = this.query().eq("parent_id", IdConstant.MENU_ROOT_ID).list();
        List<SysMenu> sysMenuList = null;

        if (roleIds.contains(IdConstant.ADMIN_ROLE_ID)){
            // 如果是超级管理员，就获取所有可用的菜单
            sysMenuList = this.query().eq("status",1).orderByAsc("sort_value").list();
        } else {
            List<Long> menuIds = getMenuIdsByRoleIds(roleIds);
            sysMenuList = this.query().in("id",menuIds).eq("status",1).list();
        }

        // 构建树形结构
        sysMenuList = MenuHelper.buildTree(roots, sysMenuList);
        // 构建路由
        return RouterHelper.buildRouters(sysMenuList);
    }

    @Override
    public List<String> findUserPermsList(List<Long> roleIds) {
        List<SysMenu> sysMenuList = null;

        if (roleIds.contains(IdConstant.ADMIN_ROLE_ID)){
            sysMenuList = this.query().eq("status",1).orderByAsc("sort_value").list();
        }else {
            List<Long> menuIds = getMenuIdsByRoleIds(roleIds);
            sysMenuList = this.query().in("id",menuIds).eq("status",1).list();
        }

        return sysMenuList.stream().map(sysMenu -> {
            if (sysMenu.getType() == 2){
                return sysMenu.getPerms();
            }
            return null;
        }).collect(Collectors.toList());
    }

    @Override
    public Result findMenuByRoleId(Long roleId) {
        // 根据roleId查找menuId
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuService.query().eq("role_id", roleId).list();
        List<Long> menuIds = sysRoleMenuList.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());

        // 查找所有可用的菜单信息
        List<SysMenu> sysMenus = this.query().eq("status",1).list();
        // 根据menuIds判断菜单权限是否被分配
        sysMenus.forEach(sysMenu -> sysMenu.setSelect(menuIds.contains(sysMenu.getId())));
        // 构建树形结构
        List<SysMenu> roots = this.query().eq("parent_id", IdConstant.MENU_ROOT_ID).list();
        return Result.ok(MenuHelper.buildTree(roots,sysMenus));
    }

    @Override
    public Result doAssign(AssignMenuVo assignMenuVo) {
        // 获取参数
        Long roleId = assignMenuVo.getRoleId();
        List<Long> menuIdList = assignMenuVo.getMenuIdList();
        Assert.isTrue(roleId != null && roleId > 0,"roleId must not be null and greater than zero.");

        List<SysRoleMenu> sysRoleMenuList = menuIdList.stream().map(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);
            return sysRoleMenu;
        }).collect(Collectors.toList());

        boolean saveBatch = sysRoleMenuService.saveBatch(sysRoleMenuList);
        return CheckUtils.check(saveBatch);
    }

    @Override
    public Result insertMenu(SysMenu sysMenu) {
        // 新增菜单
        boolean save1 = this.save(sysMenu);
        // 同时，给超级管理员也加上权限
        SysRoleMenu sysRoleMenu = new SysRoleMenu();
        sysRoleMenu.setMenuId(sysMenu.getId());
        sysRoleMenu.setRoleId(IdConstant.ADMIN_ROLE_ID);

        boolean save2 = sysRoleMenuService.save(sysRoleMenu);
        return CheckUtils.check(save1 && save2);
    }

    private List<Long> getMenuIdsByRoleIds(List<Long> roleIds){
        // 根据角色id获取菜单信息
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuService.query().in("role_id", roleIds).list();
        return sysRoleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
    }
}
